﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Data.SqlClient;
using System.Data;
using LiWeiJian.BasicClassLib;
using LiWeiJian.FileExtension;
using LiWeiJian.Data;
using System.Diagnostics;
using CsharpHttpHelper;
using CsharpHttpHelper.Enum;
using System.Drawing;
using ImageProcessor.Imaging.Formats;
using ImageProcessor;
using log4net;
using System.Reflection;
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace 共享图库维护工具
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //款号图
                GetPicOfKuanHao();
                //款色图
                GetPicOfKuanSeHao();

                //从淘宝API推送回来的商品表里下载主图
                GetKuanHaoFromTaoApi();
                //Console.WriteLine("完成");
                //Console.ReadKey();
            }
            catch (Exception ex)
            {
                ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
                log.Error($"程序出错", ex);
            }
        }

        private static void GetKuanHaoFromTaoApi()
        {
            string cnnString = Properties.Settings.Default.DianShangConnectionString;
            string dstDir = @"\\10.41.20.254\电子商务部\BI报表\整理图库\商品款号图（淘宝主图抓取）";
            string cmdText = @"SELECT  [OUTER_ID]
                                      ,[PIC_URL]
                                  FROM [DianShang].[Pub].[vw20180228图库维护_淘宝API中获取款色图待下载链接清单]";
            using (SqlDataReader reader = SqlHelper.ExecuteReader(cnnString, CommandType.Text, cmdText))
            {
                List<PicFileInfo> listPic = new List<PicFileInfo>();

                while (reader.Read())
                {
                    string itemId = reader.GetString(0).ToString();
                    string picUrl = reader.GetString(1).StartsWith("http") ? reader.GetString(1) : "http:" + reader.GetString(1);
                    listPic.Add(new PicFileInfo
                    {
                        FileName = itemId,
                        FileFullPath = picUrl
                    });
                }
                //下载图片
                DownLoadPic(listPic, dstDir);
            }

        }

        /// <summary>
        /// 获取款号图片，从图库中找寻
        /// </summary>
        private static void GetPicOfKuanHao()
        {
            string dstFoderPath = Properties.Settings.Default.dstFolderPathOfKuanHao;
            List<string> subFolderPaths = new List<string>();
            foreach (string item in Properties.Settings.Default.mainFolderPaths)
            {
                subFolderPaths.AddRange(GetSubPicFolderPath(item));
            }

            List<PicFileInfo> picFileInfos = new List<PicFileInfo>();

            picFileInfos.AddRange(GetPicInfo(subFolderPaths, dstFoderPath));

            CopyAndTranPic(dstFoderPath, picFileInfos);
        }

        /// <summary>
        /// 获取款色号图，从淘宝API中得到，引用视图[BIL1_WS].[dbo].[V_调用视图_20160127_款色号图片链接待下载_淘宝API]
        /// </summary>
        private static void GetPicOfKuanSeHao()
        {
            string dstFoderPath = Properties.Settings.Default.dstFolderPathOfKuanSeHao;
            DataSet1.vw20180228图库维护_款色号图片待下载清单DataTable dt = new DataSet1.vw20180228图库维护_款色号图片待下载清单DataTable();
            DataSet1TableAdapters.vw20180228图库维护_款色号图片待下载清单TableAdapter adp = new DataSet1TableAdapters.vw20180228图库维护_款色号图片待下载清单TableAdapter();
            adp.Fill(dt);

            List<PicFileInfo> picInfos = new List<PicFileInfo>();
            foreach (var item in dt.AsEnumerable())
            {
                picInfos.Add(new PicFileInfo { FileName = item["款色号"].ToString(), FileFullPath = item["图片链接"].ToString() });
            }
            //下载图片
            DownLoadPic(picInfos, dstFoderPath);
        }

        /// <summary>
        /// 复制图库文件，并压缩大小为400像素
        /// </summary>
        /// <param name="dstFolderPath"></param>
        /// <param name="picFileInfos"></param>
        private static void CopyAndTranPic(string dstFolderPath, List<PicFileInfo> picFileInfos)
        {
            DataSet1 ds = new DataSet1();

            DataSet1TableAdapters.tbl20180228图库维护_商品款号图库抓取记录TableAdapter adp = new DataSet1TableAdapters.tbl20180228图库维护_商品款号图库抓取记录TableAdapter();
            DataSet1.tbl20180228图库维护_商品款号图库抓取记录DataTable dt = new DataSet1.tbl20180228图库维护_商品款号图库抓取记录DataTable();
            //adp属性，批量更新
            adp.Adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
            adp.Adapter.UpdateBatchSize = 200;
            adp.Fill(dt);

            foreach (var fileInfo in picFileInfos)
            {
                if (fileInfo.FileName.Length > 0 && fileInfo.FileFullPath.Length > 0 && File.Exists(fileInfo.FileFullPath) == true)//当图片路径能找到时
                {
                    Console.WriteLine("现在正在复制图片【{0}】到目标文件夹【{1}】中", fileInfo.FileName, dstFolderPath);
                    ImageExtensions.MakeThumbnail(fileInfo.FileFullPath, Path.Combine(dstFolderPath, fileInfo.FileName), 400, 0, "W");

                    DataSet1.tbl20180228图库维护_商品款号图库抓取记录Row dr = dt.Newtbl20180228图库维护_商品款号图库抓取记录Row();
                    dr.图片名 = fileInfo.FileName;
                    dr.图片原路径 = fileInfo.FileFullPath;
                    dr.数据上传时间 = DateTime.Now;
                    dt.Rows.Add(dr);
                }
            }

            adp.Update(dt);
        }

        /// <summary>
        /// 得到图片清单，用正则来筛选款号，把符合要求的图片信息装入List中
        /// </summary>
        /// <param name="subPicFolderPaths"></param>
        /// <param name="dstFolderPath"></param>
        /// <returns></returns>
        private static List<PicFileInfo> GetPicInfo(List<string> subPicFolderPaths, string dstFolderPath)
        {
            Regex reg = new Regex(@"\\([a-zA-Z0-9]{8,9}).*?\\");
            string fileName;
            string fileFullPath = string.Empty;
            string[] fileExts = { ".jpg", ".png", ".gif" };
            bool isPicExist = false;
            List<PicFileInfo> PicInfos = new List<PicFileInfo>();

            try
            {

                foreach (var picFolder in subPicFolderPaths)
                {
                    fileName = reg.Match(picFolder).Groups[1].Value;
                    //当目标文件夹里有当前文件时，不作处理
                    foreach (var fileExt in fileExts)//查找3种后缀名
                    {
                        isPicExist = false;
                        if (File.Exists(Path.Combine(dstFolderPath, fileName + fileExt)) == true)
                        {
                            isPicExist = true;
                            break;
                        }
                    }
                    //当在图库里找不到图片
                    if (isPicExist == false)
                    {
                        //规则改变了，不再是之前的800m/800p之类的，改成tbz (1)
                        string[] arrKeyWords = { "tbz*1", "tmz*1" };
                        fileFullPath = string.Empty;
                        foreach (var keyWord in arrKeyWords)
                        {
                            //需要判断where是不是有效的图片,picFolder已经是最外层的子文件夹，在此文件里直接找到最终的图片，不用遍历子文件夹
                            fileFullPath = Directory.EnumerateFiles(picFolder, "*" + keyWord + "*").Where(x => FileFunc.IsValidPicFile(x)).FirstOrDefault();
                            if (fileFullPath != null)
                                break;
                        }
                        if (!string.IsNullOrEmpty(fileFullPath))
                        {
                            PicInfos.Add(new PicFileInfo { FileName = fileName + Path.GetExtension(fileFullPath), FileFullPath = fileFullPath });
                        }
                        else
                        {
                            string cmdText = $"  INSERT    INTO [Pub].[tbl20180228图库维护_款号文件命名不规范清单]( [款号], [文件夹路径], [数据上传时间] ) VALUES ( '{fileName}', '{picFolder}', GETDATE() )";
                            SqlHelper.ExecuteNonQuery(Properties.Settings.Default.DianShangConnectionString, CommandType.Text, cmdText);
                        }

                    }

                }

                var query = from p in PicInfos
                            select new
                            {
                                FileFullPath = p.FileFullPath,
                                FileName = p.FileName
                            } into pics
                            orderby pics.FileName
                            select new PicFileInfo { FileName = pics.FileName, FileFullPath = pics.FileFullPath };
                return query.GroupBy(s => s.FileName).Select(s => s.First()).ToList();//拿OrderIndex排序后的第1条记录，即用m.jpg、主图1优先的
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// <summary>
        /// 遍历子文件夹，获取有主图字样的文件夹
        /// </summary>
        /// <param name="mainFolderPath"></param>
        /// <returns></returns>
        private static List<string> GetSubPicFolderPath(string mainFolderPath)
        {
            //Regex regex = new Regex(pattern, options);
            string patternNotMatch = @"主图|\w+$";//最外层文件夹不是以前的主图命名，或者不是款号文件夹为最外层，最外层文件夹应是【1.豆沙红】这种形式，有中文的。
            string patternMatch = @"\w{9}";//取到包含有款号的文件夹，即拿到最终是【1.豆沙红】的文件夹，因包含款号，下一级文件夹就是【1.豆沙红】。
            RegexOptions options = RegexOptions.ECMAScript; //文件夹全是英文字母+数字，即款号文件夹
            var subFolders = Directory.EnumerateDirectories(mainFolderPath, "*", SearchOption.AllDirectories);
            return subFolders.Where(s => !Regex.IsMatch(s, patternNotMatch, options)).Where(s => Regex.IsMatch(s, patternMatch, options)).ToList();

            //20170420图库规则改变，之前的用主图的规则取消重新写。
            //return Directory.EnumerateDirectories(mainFolderPath, "主图*", SearchOption.AllDirectories).ToList();
        }


        /// <summary>
        /// 根据图片网络路径下载图片
        /// </summary>
        /// <param name="picFileInfos"></param>
        /// <param name="dstFolderPath"></param>
        private static void DownLoadPic(List<PicFileInfo> picFileInfos, string dstFolderPath)
        {
            HttpHelper http = new HttpHelper();

            foreach (var picInfo in picFileInfos)
            {
                try
                {
                    Console.WriteLine($"现在进行的是款号ID:【{picInfo.FileName}】的图片收集");
                    HttpItem item = new HttpItem()
                    {
                        URL = picInfo.FileFullPath,//URL     必需项
                        Method = "GET",//URL     可选项 默认为Get
                        Timeout = 100000,//连接超时时间     可选项默认为100000
                        ReadWriteTimeout = 30000,//写入Post数据超时时间     可选项默认为30000
                        IsToLower = false,//得到的HTML代码是否转成小写     可选项默认转小写
                        Cookie = "",//字符串Cookie     可选项
                        UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0",//用户的浏览器类型，版本，操作系统     可选项有默认值
                        Accept = "text/html, application/xhtml+xml, */*",//    可选项有默认值
                        ContentType = "text/html",//返回类型    可选项有默认值
                        Allowautoredirect = false,//是否根据３０１跳转     可选项
                        ResultType = ResultType.Byte,//返回数据类型，是Byte还是String
                    };
                    HttpResult result = http.GetHtml(item);
                    Size size = new Size(300, 0);
                    string fileFullPath = Path.Combine(dstFolderPath, picInfo.FileName + ".jpg");
                    DownLoadPicByResize(result.ResultByte, size, 90, fileFullPath);
                }
                catch (Exception)
                {
                    //有可能网络访问过程中会报错
                }
            }

        }

        private static void DownLoadPicByResize(byte[] photoBytes, Size size, int quality, string fileFullPath)
        {
            using (MemoryStream inStream = new MemoryStream(photoBytes))
            {
                using (MemoryStream outStream = new MemoryStream())
                {
                    // Initialize the ImageFactory using the overload to preserve EXIF metadata.
                    using (ImageFactory imageFactory = new ImageFactory(preserveExifData: true))
                    {
                        // Load, resize, set the format and quality and save an image.
                        imageFactory.Load(inStream)
                                     .Resize(size)
                                     .Quality(quality)
                                     .Save(fileFullPath);
                    }
                    //return  Image.FromStream(outStream);
                }
            }
        }
    }
}
